home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Misc Servers / Zope.exe / DUMBLISPGEN.PY < prev    next >
Encoding:
Text File  |  1999-07-28  |  7.0 KB  |  237 lines

  1.  
  2. #
  3. # test for kjParseBuild module automatic parser generation
  4. #
  5. # lisp lists with strings, ints, vars, and setq
  6.  
  7. import string
  8.  
  9. ### The string representation for the grammar.
  10. ### Since this is used only by GrammarBuild()
  11. ### it could be put in a separate file with GrammarBuild()
  12. ### to save space/load time after Grammar compilation.
  13. ###
  14. GRAMMARSTRING ="""
  15.        Value ::  ## indicates Value is the root nonterminal for the grammar
  16.          @R SetqRule :: Value >> ( setq var Value )
  17.          @R ListRule :: Value >> ( ListTail
  18.          @R TailFull :: ListTail >> Value ListTail
  19.          @R TailEmpty :: ListTail >> )
  20.          @R Varrule :: Value >> var
  21.          @R Intrule :: Value >> int
  22.          @R Strrule :: Value >> str
  23. """
  24.  
  25. ### the name of the file in which to create the compiled
  26. ### grammar declarations
  27. COMPILEDFILENAME = "TESTLispG2.py"
  28.  
  29. ### declare comment form(s) as regular expressions 
  30. LISPCOMMENTREGEX = ";.*"
  31.  
  32. ### declare regular expression string constants for terminals
  33.  
  34. #integer terminal::::::: 
  35. INTREGEX = "["+string.digits+"]+"
  36.  
  37. #string terminal:::::::: 
  38. STRREGEX = '"[^\n"]*"'
  39.  
  40. #var terminal:::::::: 
  41. VARREGEX = "["+string.letters+"]["+string.letters+string.digits+"]*"
  42.  
  43. ### declare interpretation functions for terminals
  44.  
  45. # int interpretation function: translates string to int: 
  46. # Could use string.atoi without the extra level of indirection 
  47. # but for demo purposes here it is.  
  48. def intInterp( str ):
  49.    return string.atoi(str)
  50.  
  51. # interpretation function for strings strips off the surrounding quotes.  
  52. def stripQuotes( str ):
  53.    if len(str)<2:
  54.       TypeError, "string too short?"
  55.    return str[1:len(str)-1]
  56.  
  57. # interpretation function for vars just returns the recognized string
  58. def echo(string):
  59.    return string
  60.  
  61. # This function declares the nonterminals both in the 
  62. # "grammar generation phase" and in loading the compiled 
  63. # grammar after generation 
  64. def DeclareTerminals(Grammar):
  65.    Grammar.Addterm("int", INTREGEX, intInterp)
  66.    Grammar.Addterm("str", STRREGEX, stripQuotes)
  67.    Grammar.Addterm("var", VARREGEX, echo)
  68.  
  69. ### declare the rule reduction interpretation functions.
  70.  
  71. # EchoValue() serves for Intrule and Strrule, since 
  72. # we just want to echo the value returned by the 
  73. # respective terminal interpretation functions.  
  74. # Parser delivers list of form [ interpreted_value ] 
  75. def EchoValue( list, Context ):
  76.    if len(list)!=1:
  77.       raise TypeError, "this shouldn't happen! (1)"
  78.    return list[0]
  79.  
  80. # for Varrule interpreter must try to look up the value 
  81. # in the Context dictionary 
  82. # Parser delivers list of form [ var_name ] 
  83. def VarValue( list, Context ):
  84.    if len(list)!=1:
  85.       raise TypeError, "Huh? (2)"
  86.    varName = list[0]
  87.    if Context.has_key(varName):
  88.       return Context[varName]
  89.    else:
  90.       raise NameError, "no such lisp variable in context "+varName
  91.  
  92. # for an empty tail, return the empty list 
  93. # Parser delivers list of form [")"] 
  94. def NilTail( list, Context ):
  95.    if len(list) != 1 or list[0] != ")":
  96.       return TypeError, "Bad reduction?"
  97.    return []
  98.  
  99. # For a full tail, add the new element to the front of the list 
  100. # Parser delivers list of form [Value, TailValue] 
  101. def AddToList( list, Context ):
  102.    if len(list) !=2:
  103.       return TypeError, "Bad reduction?"
  104.    return [ list[0] ] + list[1]
  105.  
  106. # For a list, simply return the list determined by the tail 
  107. # Parser delivers list of form ["(", TailValue ] 
  108. def MakeList( list, Context ):
  109.    if len(list)!=2 or list[0]!="(":
  110.       raise TypeError, "Bad reduction? (3)"
  111.    return list[1]
  112.  
  113. # For a setq, declare a new variable in the Context dictionary 
  114. # Parser delivers list of form # ["(", "setq", varName, Value, ")"] 
  115. def DoSetq( list, Context):
  116.    if len(list) != 5\
  117.      or list[0] != "("\
  118.      or list[1] != "setq"\
  119.      or list[4] != ")":
  120.       print list
  121.       raise TypeError, "Bad reduction? (4)"
  122.    VarName = list[2]
  123.    if type(VarName) != type(''):
  124.       raise TypeError, "Bad var name? (5)"
  125.    Value = list[3]
  126.    # add or set the variable in the Context dictionary
  127.    Context[ VarName ] = Value
  128.    return Value
  129.  
  130. # This function Binds the named rules of the Grammar string to their 
  131. # interpretation functions in a Grammar.  
  132. def BindRules(Grammar):
  133.     Grammar.Bind( "Intrule", EchoValue )
  134.     Grammar.Bind( "Strrule", EchoValue )
  135.     Grammar.Bind( "Varrule", VarValue )
  136.     Grammar.Bind( "TailEmpty", NilTail )
  137.     Grammar.Bind( "TailFull", AddToList )
  138.     Grammar.Bind( "ListRule", MakeList )
  139.     Grammar.Bind( "SetqRule", DoSetq )
  140.  
  141. # This function generates the grammar and dumps it to a file.  
  142. # Since it will be used only once (after debugging), 
  143. # it probably should be put in another file save memory/load-time.  
  144. #
  145. # the result returned is a Grammar Object that can be used 
  146. # for testing/debugging purposes.  
  147. #
  148. # (maybe this should be made into a generic function?)  
  149. def GrammarBuild():
  150.     import kjParseBuild
  151.  
  152.     # initialize a Null compilable grammar to define
  153.     LispG = kjParseBuild.NullCGrammar()
  154.     
  155.     # declare terminals for the grammar
  156.     DeclareTerminals(LispG)
  157.  
  158.     # declare the keywords for the grammar
  159.     # defun is not used, included here for demo purposes only
  160.     LispG.Keywords("setq defun")
  161.  
  162.     # Declare punctuations
  163.     # dot is not used here
  164.     LispG.punct("().")
  165.  
  166.     # Declare Nonterms
  167.     LispG.Nonterms("Value ListTail")
  168.  
  169.     # Declare comment forms
  170.     LispG.comments([LISPCOMMENTREGEX])
  171.  
  172.     # Declare rules
  173.     LispG.Declarerules(GRAMMARSTRING)
  174.  
  175.     # Compile the grammar
  176.     LispG.Compile()
  177.  
  178.     # Write the grammar to a file except for
  179.     # the function bindings (which must be rebound)
  180.     outfile = open(COMPILEDFILENAME, "w")
  181.     LispG.Reconstruct("LispG",outfile,"GRAMMAR")
  182.     outfile.close()
  183.  
  184.     # for debugging purposes only, bind the rules
  185.     # in the generated grammar
  186.     BindRules(LispG)
  187.  
  188.     # return the generated Grammar
  189.     return LispG
  190.  
  191. # this function initializes the compiled grammar from 
  192. # generated file.  
  193. def LoadLispG():
  194.     import TESTLispG2
  195.     # make sure we have most recent version (during debugging)
  196.     reload(TESTLispG2)
  197.     # evaluate the grammar function from generated file
  198.     LispG = TESTLispG2.GRAMMAR()
  199.     # bind the semantics functions
  200.     DeclareTerminals(LispG)
  201.     BindRules(LispG)
  202.     return LispG
  203.  
  204. ########## test grammar generation
  205.  
  206. # do generation
  207. Dummy = GrammarBuild()
  208.  
  209. # load the grammar from the file as LispG
  210. LispG = LoadLispG()
  211.  
  212. # declare an initial context, and do some tests.
  213. Context = { "x":3 }
  214. test1 = LispG.DoParse1( "()", Context)
  215. test2 = LispG.DoParse1( "(123)", Context)
  216. test3 = LispG.DoParse1( "(x)", Context)
  217. test4 = LispG.DoParse1( '" a string "', Context)
  218. test5 = LispG.DoParse1( "(setq y (1 2 3) )", Context )
  219. test6 = LispG.DoParse1( '(setq x ("a string" "another" 0))', Context )
  220. test7str = """
  221.   ; this is a lisp comment
  222.   (setq abc (("a" x)
  223.              ("b" (setq d 12))
  224.              ("c" y) ) ; another lisp comment
  225.   )
  226. """
  227. test7 = LispG.DoParse1( test7str, Context)
  228.